home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / northc / example2.lzh / top / func.c < prev    next >
C/C++ Source or Header  |  1990-08-30  |  5KB  |  257 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Tony Andrews
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  */
  11. #include "top.h"
  12.  
  13. BLOCK    *fhead;        /* head of the current function */
  14.  
  15. /*
  16.  * dofunc() - process one function
  17.  *
  18.  * Returns FALSE on end of file
  19.  */
  20. bool
  21. dofunc()
  22. {
  23.     BLOCK    *getfunc();
  24.  
  25. #ifdef    DEBUG
  26.     if (debug)
  27.         fprintf(stderr, "dofunc() - calling getfunc()\n");
  28. #endif
  29.     if ((fhead = getfunc()) == NULL)
  30.         return FALSE;
  31.  
  32.     /*
  33.      * Process the function we just read
  34.      */
  35.     bopt(fhead);    /* perform branch optimization (must be done first) */
  36.  
  37.     if (do_dflow)
  38.         rhealth(fhead);    /* perform live/dead register analysis */
  39.  
  40.     if (do_peep)
  41.         peep(fhead);    /* peephole optimizations */
  42.  
  43.     /*
  44.      * Now dump out the modified tree
  45.      */
  46. #ifdef    DEBUG
  47.     if (debug)
  48.         fprintf(stderr, "dofunc() - calling putfunc()\n");
  49. #endif
  50.     putfunc(fhead);
  51.  
  52. #ifdef    DEBUG
  53.     if (debug)
  54.         fprintf(stderr, "dofunc() - calling freesym()\n");
  55. #endif
  56.     freesym();        /* free the symbol table */
  57.  
  58.     return TRUE;
  59. }
  60.  
  61. static    bool    saw_eof = FALSE;
  62.  
  63. /*
  64.  * getfunc() - get a function and return a pointer to its starting block
  65.  *
  66.  * Returns NULL on end of file.
  67.  */
  68. BLOCK *
  69. getfunc()
  70. {
  71. #ifdef NORTHC
  72.         /* NorthC setting registers to 0 */
  73.     BLOCK    *head;    /* starting block for this function */
  74.     BLOCK    *ob;    /* the last block we read */
  75. #else
  76.     register BLOCK    *head;    /* starting block for this function */
  77.     register BLOCK    *ob;    /* the last block we read */
  78. #endif
  79.     register BLOCK    *cb;    /* the block we're currently reading */
  80.  
  81.     if (saw_eof)
  82.         return NULL;
  83.  
  84.     head = NULL;
  85.  
  86.     /*
  87.      * Starting a global function
  88.      */
  89. #ifdef NORTHC
  90.     if (stricmp(t_op, "XDEF") == 0) {
  91. #else
  92.     if (strcmp(t_op, ".globl") == 0) {
  93. #endif
  94.         /*
  95.          * Enter the symbol and mark it global.
  96.          */
  97.         head = mksym(t_arg);
  98.         head->flags |= B_GLOBAL;
  99.     
  100.         readline();
  101.     }
  102.  
  103.     ob = NULL;
  104.  
  105.     for (;;) {
  106.         if (ob == NULL) {
  107.             if (t_lab[0] != '_') {
  108.                 fprintf(stderr, "top: expected function label\n");
  109.                 exit(EXIT_FAILURE);
  110.             }
  111.             if (head == NULL)
  112.                 head = mksym(t_lab);
  113.  
  114.         } else if (t_lab[0] == '\0') {
  115.             fprintf(stderr, "top: expected block label\n");
  116.             exit(EXIT_FAILURE);
  117.         }
  118.  
  119.         if ((cb = getsym(t_lab)) == NULL)
  120.             cb = mksym(t_lab);
  121.  
  122.         /*
  123.          * The last block falls through to this one.
  124.          */
  125.         if (ob != NULL) {
  126.             ob->chain = cb;
  127.             ob->next = cb;
  128.             ob->bfall = cb;
  129.         }
  130.  
  131.         t_lab[0] = '\0';
  132.  
  133.         /*
  134.          * Now read lines until we hit a new block or another
  135.          * function.
  136.          */
  137.         for (;;) {
  138.             /*
  139.              * If we see a global, we're done with the function
  140.              */
  141. #ifdef NORTHC
  142.             if (stricmp(t_op, "xdef") == 0)
  143. #else
  144.             if (stricmp(t_op, ".globl") == 0)
  145. #endif
  146.                 return head;
  147.             /*
  148.              * If we see a function label, we're done too.
  149.              */
  150.             if (t_lab[0] == '_')
  151.                 return head;
  152.             /*
  153.              * If we see any other label, we're done with the block.
  154.              */
  155.             if (t_lab[0])
  156.                 break;
  157.  
  158.             addinst(cb, t_op, t_arg);
  159.  
  160.             /*
  161.              * If we're at EOF, note the we've hit the end of
  162.              * file, but return the function we just read.
  163.              */
  164.             if (!readline()) {
  165.                 saw_eof = TRUE;
  166.                 return head;
  167.             }
  168.         }
  169.         ob = cb;
  170.     }
  171. }
  172.  
  173. /*
  174.  * putfunc(sb) - print out the function starting at block 'sb'
  175.  *
  176.  * The 'next' pointers determine the order in which things are placed
  177.  * in the file. Branch instructions have been removed so they need to
  178.  * be replaced here on output. Conditional branches are generated if
  179.  * indicated (by non-null 'bcond'). Unconditional branches are generated
  180.  * at the end of a block if it's "fall through" block isn't going to
  181.  * be the next thing in the file.
  182.  */
  183.  
  184. #ifdef NORTHC
  185. int sNum = 0;
  186. int out_code = 0;
  187. #endif
  188.  
  189. putfunc(sb)
  190. register BLOCK    *sb;
  191. {
  192.     register BLOCK    *cb;
  193.     register INST    *ci;
  194.  
  195. #ifdef NORTHC
  196.         if(out_code==0)
  197.            fprintf(ofp, "\tSECTION\tFNUM%d,CODE\n",sNum++);
  198.         out_code = 1;
  199.     fprintf(ofp, ";\n");
  200.     fprintf(ofp, "; %s\n", sb->name);
  201.     fprintf(ofp, ";\n");
  202. #else
  203.     fprintf(ofp, "*\n");
  204.     fprintf(ofp, "* %s\n", sb->name);
  205.     fprintf(ofp, "*\n");
  206.     fprintf(ofp, "\t.text\n");
  207. #endif
  208.  
  209.     for (cb = sb; cb != NULL ;cb = cb->next) {
  210.         if (cb->flags & B_GLOBAL)
  211. #ifdef NORTHC
  212.             fprintf(ofp, "\tXDEF\t%s\n", cb->name);
  213. #else
  214.             fprintf(ofp, "\t.globl\t%s\n", cb->name);
  215. #endif
  216.  
  217.         if (*cb->name == '_')
  218.             fprintf(ofp, "%s:\n", cb->name);
  219.  
  220.         else if (cb->flags & B_LABEL)
  221.             fprintf(ofp, "%s:\n", cb->name);
  222. #ifdef    DEBUG
  223.         if (debug) {
  224. #ifdef NORTHC
  225.             fprintf(ofp, ";\n");
  226.             fprintf(ofp, "; %s, ref:%04x  set:%04x\n",
  227.                 cb->name, cb->rref, cb->rset);
  228.             fprintf(ofp, ";\n");
  229. #else
  230.             fprintf(ofp, "*\n");
  231.             fprintf(ofp, "* %s, ref:%04x  set:%04x\n",
  232.                 cb->name, cb->rref, cb->rset);
  233.             fprintf(ofp, "*\n");
  234. #endif
  235.         }
  236. #endif
  237.  
  238.         for (ci = cb->first; ci != NULL ;ci = ci->next)
  239.             putinst(ci);
  240.         /*
  241.          * If there's a conditional branch, put out the
  242.          * appropriate instruction for it.
  243.          */
  244.         if (cb->bcond != NULL && cb->bcode >= 0)
  245.             fprintf(ofp, "\t%s\t%s\n",
  246.                 opnames[cb->bcode], cb->bcond->name);
  247.         /*
  248.          * If there's a "fall through" label, and the destination
  249.          * block doesn't come next, put out a branch.
  250.          */
  251.         if (cb->bfall != NULL && cb->bfall != cb->next) {
  252.             s_badd++;
  253.             fprintf(ofp, "\tbra\t%s\n", cb->bfall->name);
  254.         }
  255.     }
  256. }
  257.